﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using LumaQQ.NET;
using LumaQQ.NET.Utils;
using LumaQQ.NET.Events;
using LumaQQ.NET.Entities;
using LumaQQ.NET.Packets;
using LumaQQ.NET.Packets.In;
using LumaQQ.NET.Packets.Out;
using LumaQQ.NET.Packets.Out._08;
using LumaQQ.NET.Packets.In._08;
using System.Drawing;
using System.IO;
namespace QQClient.cs
{
    class Program
    {
        static QQUser user = new QQUser(945371778, "qqtest12345");//   需要验证码 945371778, "qqtest12345"
        static LumaQQ.NET.QQClient client = new LumaQQ.NET.QQClient(user);

        static void Main(string[] args)
        {
            client.Error += new EventHandler<QQEventArgs<ErrorPacket>>(client_Error);

            #region 代理登录
            //user.IsUdp = false;//如果使用代理必须使用TCP登录
            //client.Proxy.ProxyHost = "192.168.7.62";
            //client.Proxy.ProxyPort = 1080;
            //client.Proxy.ProxyType = ProxyType.Socks5;
            //client.LoginServerHost = "219.133.62.10"; //tcpconn.tencent.com  TCP Server 直接服务器： 219.133.62.10
            //client.LoginPort = 80;
            #endregion

            #region 正常UDP登录
            user.IsUdp = true;
            client.LoginServer = "58.251.63.79"; //UDP Server 58.251.62.60 直接服务器 219.133.62.8，中转服务器 219.133.49.173
            #endregion

            #region 正常TCP登录
            //user.IsUdp = false;
            //client.LoginPort = 80;
            //client.LoginServerHost = "58.251.62.60"; //UDP Server  直接服务器 219.133.62.8，中转服务器 219.133.49.173 "58.251.62.60"
            #endregion

            #region PacketManager events
            //client.PacketManager.SentPacketSuccessfully += new EventHandler<QQEventArgs<_08OutPacket, _08InPacket>>(PacketManager_SentPacketSuccessfully);
            #endregion

            #region Login events
            client.LoginManager.PasswordChecked += new EventHandler<QQEventArgs<_08LoginKeyPacket, _08LoginKeyReplyPacket>>(LoginManager_PasswordChecked);
            client.LoginManager.PasswordError += new EventHandler<QQEventArgs<_08LoginKeyPacket, _08LoginKeyReplyPacket>>(LoginManager_PasswordError);
            client.LoginManager.CheckPasswordFailed += new EventHandler<QQEventArgs<_08LoginKeyPacket, _08LoginKeyReplyPacket>>(LoginManager_CheckedPasswordFailure);
            client.LoginManager.LoginSuccessfully += new EventHandler<QQEventArgs<LumaQQ.NET.Packets.Out._08._08LoginPacket, LumaQQ.NET.Packets.In._08._08LoginReplyPacket>>(LoginManager_LoginSuccessfully);
            //client.LoginManager.RequestKeySuccessfully += new EventHandler<QQEventArgs<GetKeyPacket, GetKeyReplyPacket>>(LoginManager_RequestKeySuccessfully);
            client.LoginManager.NeedVerifyCode += new EventHandler<QQEventArgs<_08LoginToken2Packet, _08LoginToken2ReplyPacket>>(LoginManager_NeedVerifyCode);
            //client.LoginManager.GetLoginToken2Successfully += new EventHandler<QQEventArgs<_08LoginToken2Packet, _08LoginToken2ReplyPacket>>(LoginManager_GetLoginToken2Successfully);
            client.LoginManager.ReceivedAuthInfo += new EventHandler<QQEventArgs<_08AuthInfoOpPacket, _08AuthInfoOpReplyPacket>>(LoginManager_ReceivedAuthInfo);
            #endregion

            #region message events
            client.MessageManager.ReceivedNormalIM += new EventHandler<QQEventArgs<ReceiveIMPacket>>(MessageManager_ReceivedNormalIM);
            client.MessageManager.UserInputingStatus += new EventHandler<QQEventArgs<ReceiveIMPacket>>(MessageManager_UserInputingStatus);

            client.MessageManager.SysAddedByOthersEx += new EventHandler<QQEventArgs<SystemNotificationPacket>>(MessageManager_SysAddedByOthersEx);
            client.MessageManager.SysRequestAddMe += new EventHandler<QQEventArgs<SystemNotificationPacket>>(MessageManager_SysRequestAddMe);
            client.MessageManager.SysRequestAddMeEx += new EventHandler<QQEventArgs<SystemNotificationPacket>>(MessageManager_SysRequestAddMeEx);


            #endregion

            #region Connection manager events
            client.ConnectionManager.NetworkError += new EventHandler<LumaQQ.NET.Events.ErrorEventArgs>(ConnectionManager_NetworkError);
            #endregion

            #region Privacy
            client.PrivacyManager.GetWeatherSuccessfully += new EventHandler<QQEventArgs<WeatherOpPacket, WeatherOpReplyPacket>>(PrivacyManager_GetWeatherSuccessfully);

            #endregion

            #region Friend
            client.FriendManager.SignatureChanged += new EventHandler<QQEventArgs<ReceiveIMPacket>>(FriendManager_SignatureChanged);
            client.FriendManager.UserPropertyChanged += new EventHandler<QQEventArgs<ReceiveIMPacket>>(FriendManager_UserPropertyChanged);

            client.FriendManager.AddFriendSuccessfully += new EventHandler<QQEventArgs<AddFriendExPacket, AddFriendExReplyPacket>>(FriendManager_AddFriendSuccessfully);
            client.FriendManager.AddFriendNeedAuth += new EventHandler<QQEventArgs<AddFriendExPacket, AddFriendExReplyPacket>>(FriendManager_AddFriendNeedAuth);
            client.FriendManager.GetFriendListSuccessfully += new EventHandler<QQEventArgs<GetFriendListPacket, GetFriendListReplyPacket>>(FriendManager_GetFriendListSuccessfully);
            client.FriendManager.GetOnlineFriendSuccessfully += new EventHandler<QQEventArgs<_08GetOnlineOpPacket, _08GetOnlineOpReplyPacket>>(FriendManager_GetOnlineFriendSuccessfully);
            client.FriendManager.GetFriendLevelSuccessfully += new EventHandler<QQEventArgs<FriendLevelOpPacket, FriendLevelOpReplyPacket>>(FriendManager_GetFriendLevelSuccessed);
            client.FriendManager.GetUserPropertySuccessfully += new EventHandler<QQEventArgs<UserPropertyOpPacket, UserPropertyOpReplyPacket>>(FriendManager_GetUserPropertySuccessed);
            client.FriendManager.AdvancedSearchUserOK += new EventHandler<QQEventArgs<AdvancedSearchUserPacket, AdvancedSearchUserReplyPacket>>(FriendManager_AdvancedSearchUserOK);
            client.FriendManager.SearchUserSuccessfully += new EventHandler<QQEventArgs<SearchUserPacket, SearchUserReplyPacket>>(FriendManager_SearchUserSuccessfully);
            #endregion
            client.Login();
            //Console.WriteLine(LumaQQ.NET.Utils.Util.GetTimeMillis(DateTime.Now));
            Console.WriteLine("回车退出登录:");
            string enter = Console.ReadLine();
            if (!string.IsNullOrEmpty(enter) && user.PuzzleToken != null)
            {
                client.LoginManager.SendToken2(user.PuzzleToken, enter, 0);
                Console.ReadLine();
            }
            else
            {
                client.Logout();
                WL("QQ退出成功！");
            }

        }

        static void LoginManager_ReceivedAuthInfo(object sender, QQEventArgs<_08AuthInfoOpPacket, _08AuthInfoOpReplyPacket> e)
        {
            if (e.OutPacket.FriendQQ != 0)
            {
                client.FriendManager.SendAddFriendAuth(e.OutPacket.FriendQQ, "我是你的好朋友啊！");
            }
        }

        static void FriendManager_SearchUserSuccessfully(object sender, QQEventArgs<SearchUserPacket, SearchUserReplyPacket> e)
        {
            WL("搜索好友成功");
            foreach (var u in e.InPacket.Users)
            {
                WL("号码:{0} 昵称:{1}", u.QQ, u.Nick);
            }
        }

        static void FriendManager_AdvancedSearchUserOK(object sender, QQEventArgs<AdvancedSearchUserPacket, AdvancedSearchUserReplyPacket> e)
        {
            WL("高级搜索好友成功");
            foreach (var u in e.InPacket.Users)
            {
                WL("号码:{0} 昵称:{1} 在线:{2}", u.QQ, u.Nick, u.Online);
            }
        }
        static void FriendManager_GetUserPropertySuccessed(object sender, QQEventArgs<UserPropertyOpPacket, UserPropertyOpReplyPacket> e)
        {
            if (e.InPacket.Finished)
            {
                WL("已经读取全部好友的属性信息");
            }
            foreach (UserProperty property in e.InPacket.Properties)
            {
                WL("用户属性： QQ:{0} 属性值：{1}", property.QQ, property.Property);
            }
        }

        static void FriendManager_GetFriendLevelSuccessed(object sender, QQEventArgs<FriendLevelOpPacket, FriendLevelOpReplyPacket> e)
        {
            WL("成功查询好友等级");
            foreach (FriendLevel level in e.InPacket.FriendLevels)
            {
                WL("QQ：{0} 等级：{1} 活动天数:{2} 升级天数：{3}", level.QQ, level.Level, level.ActiveDays, level.UpgradeDays);
            }
        }
        static void FriendManager_GetOnlineFriendSuccessfully(object sender, QQEventArgs<_08GetOnlineOpPacket, _08GetOnlineOpReplyPacket> e)
        {
            if (e.InPacket.Finished)
            {
                WL("共得到{0}位在线好友", client.QQUser.Friends.Onlines);
                //  e.QQClient.FriendManager.AddFriend(630377892);
            }
            else
            {
                WL("本次共得到{0}位在线好友", e.InPacket.OnlineFriends.Count);
            }
        }

        static void FriendManager_GetFriendListSuccessfully(object sender, QQEventArgs<GetFriendListPacket, GetFriendListReplyPacket> e)
        {
            if (e.InPacket.Finished)
            {
                WL("共得到{0}位好友", client.QQUser.Friends.Count);
                WL("开始读取好友");
                client.FriendManager.GetOnlineFriend();
                int i = 0;
                List<int> list = new List<int>();
                foreach (FriendInfo info in client.QQUser.Friends.Values)
                {
                    WL("第" + (i++).ToString() + "位好友：" + info.BasicInfo.Nick + "(" + info.BasicInfo.QQ.ToString() + ")");

                    //修改好友备注   默认不修改，只有当要测试时再启用代码
                    //FriendRemark remark = new FriendRemark();
                    //remark.Name = "好友" + i.ToString();
                    //e.QQClient.FriendManager.UploadFriendRemark(info.BasicInfo.QQ, remark);

                    list.Add(info.BasicInfo.QQ);
                }
                //查询好友等级
                client.FriendManager.GetFriendLevel(list);

                //读取好友属性信息
                client.FriendManager.GetUserProperty(0);

                var friendQQ = 123456;
                client.FriendManager.AddFriend(friendQQ);
            }
            else
            {
                WL("本次共得到{0}位好友", e.InPacket.Friends.Count);
            }
        }

        static void FriendManager_AddFriendSuccessfully(object sender, QQEventArgs<AddFriendExPacket, AddFriendExReplyPacket> e)
        {
            WL("添加好友{0}成功", e.InPacket.FriendQQ);
        }

        static void FriendManager_AddFriendNeedAuth(object sender, QQEventArgs<AddFriendExPacket, AddFriendExReplyPacket> e)
        {
            WL("添加好友需要验证信息");
            client.LoginManager.User_AuthInfoOpPacket(e.InPacket.FriendQQ);

        }

        static void MessageManager_SysAddedByOthersEx(object sender, QQEventArgs<SystemNotificationPacket> e)
        {
            WL("{0}使用0x00A8命令把我加为好友", e.Packet.From);
            client.FriendManager.AddFriend(e.Packet.From);
        }

        static void MessageManager_SysRequestAddMeEx(object sender, QQEventArgs<SystemNotificationPacket> e)
        {
            WL("{0}使用0x00A8命令请求加我为好友,附加信息:{1}", e.Packet.From, e.Packet.Message);
            client.FriendManager.ApprovedAddMe(e.Packet.From);
            client.FriendManager.AddFriend(e.Packet.From);
        }

        static void MessageManager_SysRequestAddMe(object sender, QQEventArgs<SystemNotificationPacket> e)
        {

            WL("{0}请求加我为好友,附加信息:{1}", e.Packet.From, e.Packet.Message);
            client.FriendManager.AddFriend(e.Packet.From);
        }

        static void FriendManager_UserPropertyChanged(object sender, QQEventArgs<ReceiveIMPacket> e)
        {
            WL("好友{0}更改属性:{1}", e.Packet.PropertyChange.QQ, e.Packet.PropertyChange.Property);
        }

        static void FriendManager_SignatureChanged(object sender, QQEventArgs<ReceiveIMPacket> e)
        {
            WL("好友{0}更改了新签名:{1}", e.Packet.SignatureOwner, e.Packet.Signature);
        }

        static void LoginManager_GetLoginToken2Successfully(object sender, QQEventArgs<_08LoginToken2Packet, _08LoginToken2ReplyPacket> e)
        {
            WL("GetLoginToken2Successfully");
        }

        static void PrivacyManager_GetWeatherSuccessfully(object sender, QQEventArgs<WeatherOpPacket, WeatherOpReplyPacket> e)
        {
            WL("本地天气预报:省：{0} ；市:{1}", e.InPacket.Province, e.InPacket.City);
            foreach (var weather in e.InPacket.Weathers)
            {
                WL(weather.ToString());
            }
        }

        static void MessageManager_UserInputingStatus(object sender, QQEventArgs<ReceiveIMPacket> e)
        {
            WL("用户{0}正在输入文本", e.Packet.MemberQQ);
        }

        static void MessageManager_ReceivedNormalIM(object sender, QQEventArgs<ReceiveIMPacket> e)
        {
            if (e.Packet.NormalIM.Message.Trim() == "关机")
            {
                client.MessageManager.SendIM(e.Packet.NormalHeader.Sender, "5秒后关机");
                System.Diagnostics.Process.Start("c:\\windows\\system32\\shutdown.exe", "-i");
            }
            WL("接收到来自{0}的消息，内容：{1}", e.Packet.NormalHeader.Sender, e.Packet.NormalIM.Message);
            client.MessageManager.SendIM(e.Packet.NormalHeader.Sender, "自动回复：" + e.Packet.NormalIM.Message);

        }


        #region Login events
        //static List<byte> puzzleData = new List<byte>();
        static void LoginManager_NeedVerifyCode(object sender, QQEventArgs<_08LoginToken2Packet, _08LoginToken2ReplyPacket> e)
        {

            string puzzleFile = "D:\\verifyCode.jpg";
            //验证码下载完，保存验证码
            using (FileStream fs = new FileStream(puzzleFile, FileMode.Create, FileAccess.Write, FileShare.Write))
            {
                fs.Write(user.PuzzleAllData.ToArray(), 0, user.PuzzleAllData.Count);
            }


            WL("需要验证码，验证码图片已保存在：{0},请查年后输入验证码：", puzzleFile);


        }
        static void LoginManager_RequestKeySuccessfully(object sender, QQEventArgs<GetKeyPacket, GetKeyReplyPacket> e)
        {
            WL("请求Key成功 SubCommand:{0}", e.InPacket.SubCommand);
        }

        static void LoginManager_LoginSuccessfully(object sender, QQEventArgs<LumaQQ.NET.Packets.Out._08._08LoginPacket, LumaQQ.NET.Packets.In._08._08LoginReplyPacket> e)
        {
            WL("登录成功");

            //天气预报
            client.PrivacyManager.GetWeather();

            //下载所有好友
            client.FriendManager.GetFriendList();

            client.FriendManager.SearchUser(0);
        }
        static void LoginManager_CheckedPasswordFailure(object sender, QQEventArgs<_08LoginKeyPacket, _08LoginKeyReplyPacket> e)
        {
            WL("检查密码错误");
        }

        static void LoginManager_PasswordError(object sender, QQEventArgs<_08LoginKeyPacket, _08LoginKeyReplyPacket> e)
        {
            WL("密码错误");
        }

        static void LoginManager_PasswordChecked(object sender, QQEventArgs<_08LoginKeyPacket, _08LoginKeyReplyPacket> e)
        {
            WL("密码正确");
        }
        #endregion

        static void PacketManager_SentPacketSuccessfully(object sender, QQEventArgs<_08OutPacket, _08InPacket> e)
        {
            WL("[{0}]发送成功,确认包：{1}", e.OutPacket.ToString(), e.InPacket);
        }

        static void client_Error(object sender, QQEventArgs<ErrorPacket> e)
        {
            Console.WriteLine("接收到错误包：{0}", e.Packet.ErrorMessage);
        }

        static void ConnectionManager_NetworkError(object sender, LumaQQ.NET.Events.ErrorEventArgs e)
        {
            WL("ConnectionManager_NetworkError");
            Console.WriteLine(e.Exception.Message);
            Console.WriteLine(e.Exception.StackTrace);
        }

        #region Helper methods

        private static void WL(object text, params object[] args)
        {
            Console.WriteLine(text.ToString(), args);
        }

        private static void RL()
        {
            Console.ReadLine();
        }

        private static void Break()
        {
            System.Diagnostics.Debugger.Break();
        }

        #endregion
    }
}
